﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System.ComponentModel;
using System.Windows;

namespace Xceed.Silverlight.ListBox.PositioningFunction
{
  internal abstract class PositioningFunctionBase : INotifyPropertyChanged
  {
    internal static Point InvalidPosition = new Point( -999, -999 );

    #region DisplayName Property

    internal abstract string DisplayName
    {
      get;
    }

    #endregion

    #region IsScrollOffsetDifferenceBetweenPositionsSupported Property

    internal virtual bool IsScrollOffsetDifferenceBetweenPositionsSupported
    {
      get
      {
        return false;
      }
    }

    #endregion

    #region EffectiveViewportStart Property
    protected internal double EffectiveViewportStart
    {
      get;
      set;
    }
    #endregion

    #region EffectiveViewportEnd Property
    protected double EffectiveViewportEnd
    {
      get;
      set;
    }
    #endregion

    #region ExtendedViewportStart Property
    protected double ExtendedViewportStart
    {
      get;
      set;
    }
    #endregion

    #region ExtendedViewportEnd Property
    protected double ExtendedViewportEnd
    {
      get;
      set;
    }
    #endregion

    #region IndexPositionTopBottom Property
    protected double IndexPositionTopBottom
    {
      get;
      set;
    }
    #endregion

    #region IndexPositionBottomUp Property
    protected double IndexPositionBottomUp
    {
      get;
      set;
    }
    #endregion

    #region StartOffsetIndex Property
    protected double StartOffsetIndex
    {
      get;
      set;
    }
    #endregion

    #region Internal Abstract Methods
    internal abstract void PrepareLayoutPass( double partialOffset, Size itemContainerSize, Size groupContainerSize );

    internal abstract void UpdateEffectiveViewportSizeInPixels( Size newViewportSizeInPixels );

    internal abstract void PlaceContainerForward( Size container,
      bool isGroupContainer,
      out Point containerPosition,
      out double containerProportionInViewport,
      out int layoutProgressionPercentage,
      out double rotateAngle );

    internal abstract void PlaceContainerBackward( Size container,
      bool isGroupContainer,
      out Point containerPosition,
      out double containerProportionInViewport,
      out int layoutProgressionPercentage,
      out double rotateAngle );

    internal abstract Point GetBringIntoViewPositionForContainer( Size groupHeaderContainerSize,
      Size itemContainerSize,
      Size viewportSize,
      bool forwardScrolling );

    internal abstract double GetScrollOffsetDifferenceBetweenPositions( Point originalPosition, Point targetPosition, Size containerSize );

    internal abstract Rect GetCorrectedViewportVisibilityRect( Size groupHeaderSize, Rect viewportVisibilityRect );

    internal abstract void CorrectViewportSize( double itemsInViewport, ref Size viewport );

    internal abstract Point PlaceStickyHeader( Point lastContainerOfTheGroupPosition, Size containerSize, out double angle );

    internal abstract double GetGroupHeaderProportion();

    internal abstract Size GetCorrectedContainerSize( Size containerSize, Size viewportSize );
    #endregion

    #region Protected Internal Methods
    protected internal abstract double GetContainerProportionInEffectiveViewport( Size containerSize, Point containerPosition );

    protected internal void ResetPositioningIndexes()
    {
      this.IndexPositionBottomUp = this.StartOffsetIndex;
      this.IndexPositionTopBottom = this.StartOffsetIndex;
    }
    #endregion

    #region Internal Methods
    internal bool IsLayoutFilled( bool forward )
    {
      if( forward )
      {
        return this.IndexPositionTopBottom > this.ExtendedViewportEnd;
      }
      else
      {
        return this.IndexPositionBottomUp < this.ExtendedViewportStart;
      }
    }
    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    internal virtual void NotifyPropertyChanged( string propertyName )
    {
      if( PropertyChanged != null )
      {
        PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
      }
    }

    #endregion

  }
}
